import random
from utils.tencent import sms
from web.forms.bootstrap import BootStrapFrom
from django import forms
from web import models
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
from django.conf import settings
from django_redis import get_redis_connection
from utils import encrypt



#页面表单展示
class RegisterModelForm(BootStrapFrom,forms.ModelForm):
    mobile_phone = forms.CharField(label='手机号',validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$','手机号格式错误')],)
    password = forms.CharField(label='密码',min_length=8,max_length=64,error_messages={'min_length':'密码长度不能少于8个字符','max_length':'密码长度不能多于64个字符'},widget=forms.PasswordInput(attrs={'class':'form-control'}))   #变为密文
    confirm_password = forms.CharField(label='重复密码',widget=forms.PasswordInput(attrs={'class':'form-control','placeholder':'请输入新密码'}))
    code = forms.CharField(label='验证码',widget=forms.TextInput(attrs={'class':'form-control','placeholder':'请输入验证码'}))


    class Meta:
        model = models.UserInfo
        fields = ['username','email','password','confirm_password','mobile_phone','code']


    #用户名重复校验
    def clean_username(self):
        username = self.cleaned_data['username']
        exists = models.UserInfo.objects.filter(username=username).exists()
        if exists:
            raise ValidationError('当前用户名存在')
        return username
    #邮箱重复校验
    def clean_email(self):
        email = self.cleaned_data['email']
        exists = models.UserInfo.objects.filter(email=email).exists()
        if exists:
            raise ValidationError('当前邮箱已存在')
        return email
    def clean_password(self):
        pwd = self.cleaned_data['password']
        #加密密码
        return encrypt.md5(pwd)

    #重复密码对比验证   注意优先级
    def clean_confirm_password(self):
        pwd = self.cleaned_data['password']  #取得密码
        #重复密码加密比较
        confirm_password = encrypt.md5(self.cleaned_data['confirm_password'])  #取得重复输入的密码
        if pwd != confirm_password:
            raise ValidationError('两次输入密码不一致')

        return confirm_password
    #手机号校验
    def clean_mobile_phone(self):
        mobile_phone = self.cleaned_data['mobile_phone']
        exists = models.UserInfo.objects.filter(mobile_phone=mobile_phone).exists()
        if exists:
            raise ValidationError('当前手机号已注册')
        return mobile_phone
    #验证码校验
    def clean_code(self):
        code = self.cleaned_data['code']
        mobile_phone = self.cleaned_data.get('mobile_phone')
        if not mobile_phone:
            return code
        conn = get_redis_connection()
        redis_code = conn.get(mobile_phone)
        if not redis_code:
            raise ValidationError('验证码失效或未发送,请重新发送')
        redis_str_code = redis_code.decode('utf-8')

        #判断验证码是否输入正确
        if code.strip() !=redis_str_code:
            raise ValidationError('验证码输入错误，请重新输入')
        return code


#短信模板
class SendSmsForm(forms.Form):
    mobile_phone = forms.CharField(label='手机号',validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$','手机号格式错误')],)

    def __init__(self,request,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.request = request
    def clean_mobile_phone(self):
        """手机号校验功能"""
        mobile_phone = self.cleaned_data['mobile_phone']
        tpl = self.request.GET.get('tpl')
        template_id = settings.TENCENT_SMS_TEMPLATE.get(tpl)
        if not template_id:
            raise ValidationError('短信模板错误')
        exist = models.UserInfo.objects.filter(mobile_phone=mobile_phone).exists()
        if tpl =='login':
            if not exist:
                raise ValidationError('手机号不存在')
        else:
        #校验数据库中是否有手机号
            if exist:
                raise ValidationError("手机号已经存在")
        #发短信 计算时长
        code_ie = str(random.randrange(100000, 999999))
        code = []
        code.append(code_ie)

        ph_number_ie = '+86'

        ph_number = []
        ph_number.append(ph_number_ie + mobile_phone)
        result = sms.send_sms(ph_number, code, template_id)
        if result == None:
            raise ValidationError("短信发送失败")

        conn = get_redis_connection()
        conn.set(mobile_phone,code_ie,ex=60)
        return mobile_phone


#登录短信模板Form
class LoginSmsForm(BootStrapFrom,forms.Form):
    mobile_phone = forms.CharField(label='手机号', validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$', '手机号格式错误')], )
    code = forms.CharField(label='验证码',
                           widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '请输入验证码'}))
    def clean_mobile_phone(self):
        mobile_phone = self.cleaned_data['mobile_phone']
        #查询后台内是否有该用户对象
        user_object = models.UserInfo.objects.filter(mobile_phone=mobile_phone).first()
        if not user_object:
            raise ValidationError("手机号不存在")
        return user_object

    def clean_code(self):
        code = self.cleaned_data['code']
        user_object = self.cleaned_data.get('mobile_phone')
        #手机号不存在，则验证码无需校验
        if not user_object:
            return code
        #手机号存在，开始校验
        conn = get_redis_connection()
        redis_code = conn.get(user_object.mobile_phone)
        if not redis_code:
            raise ValidationError('验证码失效或未发送,请重新发送')
        redis_str_code = redis_code.decode('utf-8')

        #判断验证码是否输入正确
        if code.strip() !=redis_str_code:
            raise ValidationError('验证码输入错误，请重新输入')
        return code
#登录密码模板Form
class LoginForm(BootStrapFrom,forms.Form):
    username = forms.CharField(label='邮箱或手机号')
    password = forms.CharField(label='密码', min_length=8, max_length=64,
                               error_messages={'min_length': '密码长度不能少于8个字符', 'max_length': '密码长度不能多于64个字符'},
                               widget=forms.PasswordInput(attrs={'class': 'form-control'},render_value=True))  # 变为密文
    code = forms.CharField(label='图片验证码')
    def __init__(self,request,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.request = request
    def clean_password(self):
        #密码加密
        password = self.cleaned_data['password']
        return encrypt.md5(password)

    def clean_code(self):
        """校验图片验证码"""
        #用户输入的验证码
        code = self.cleaned_data['code']
        print(code)
        #session中保存的验证码
        session_code = self.request.session.get('image_code') #获取不存在的验证码
        if not session_code:
            raise ValidationError('验证码已过期,请刷新重新获取')

        #.strip().upper() 系统判断忽略用户输入的验证码大小写与空格
        if code.strip().upper() != session_code.strip().upper():
            raise ValidationError("验证码输入错误，请重新输入")
        return code